package com.boge.socket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.boge.parse.amf.AmfProtocolCodecFilter;

/**
 * 服务器接收器
 * @author boge
 */
public class ServerAcceptor {

	private NioSocketAcceptor acceptor = new NioSocketAcceptor();
	private ActionDispatcher dispatcher = new ActionDispatcher();
	
	public ServerAcceptor(SessionListener sessionListener) {
		this(sessionListener, new AmfProtocolCodecFilter());
	}
	
	public ServerAcceptor(SessionListener sessionListener, ProtocolCodecFactory protocolCodecFactory) {
		acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(protocolCodecFactory));
		acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));  
		acceptor.setHandler(dispatcher);
		
		SocketSessionConfig config = acceptor.getSessionConfig();
		config.setReadBufferSize(2048);
		config.setIdleTime(IdleStatus.BOTH_IDLE, 10);//第一个参数用于指定空闲状态，第二个参数用于指定Session的闲置时间（单位秒），此处含义为：读写 通道均在3 秒内无任何操作就进入空闲状态
		dispatcher.addSessionListener(sessionListener);
	}

	/**
	 * 注册动作
	 * @param handler 处理器
	 * @param actions 动作
	 */
	public void registerAction(ActionHandler<?> handler, int ...actions) {
		for(int action:actions){
			dispatcher.registerAction(action, handler);
		}
	}
	/**
	 * 删除动作
	 * @param actions 动作
	 */
	public void removeAction(int ...actions) {
		for(int action:actions){
			dispatcher.removeAction(action);
		}
	}
	/**
	 * 获取动作
	 * @param action 动作
	 * @return 
	 */
	public ActionHandler<?> getAction(int action) {
		return dispatcher.getAction(action);
	}
	
	/**
	 * 绑定一个端口
	 * @param port 端口
	 * @throws IOException
	 */
	public void bind(int port) throws IOException {
		acceptor.bind(new InetSocketAddress(port));
	}
	
	/**
	 * 释放此服务分配的任何资源。请注意，此方法可能会阻塞，只要有此服务管理的任何会话。
	 */
	public void stop() {
		acceptor.dispose();
	}

	public NioSocketAcceptor getAcceptor() {
		return acceptor;
	}

	public ActionDispatcher getDispatcher() {
		return dispatcher;
	}
	
}
